﻿using System.Diagnostics;
using System.Text;
using System.Xml.Linq;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Log;
using UtilZ.Dotnet.Ex.Model;

namespace AOTToolConsoleApp
{
    unsafe internal class Program
    {
        static void Main(string[] args)
        {
            TestLog();

            string path = PathEx.ExecutablePath;
            Console.WriteLine(path);
            //ITool tool = new DiskDataFillTool();
            //ITool tool = new CodeMergerTool();
            //ITool tool = new WPSRemoveNetdiskTool();
            //tool.Excute(args);

            //TestMemoryPoolZPeromance2();
            Console.WriteLine("任意键结束");
            Console.ReadKey();
        }

        private static void TestLog()
        {
            Loger.Trace("Trace");
            Loger.Debug("Debug");
            Loger.Info("Info");
            Loger.Warn("Warn");
            Loger.Error("Error");
            Loger.Fatal("Fatal");

            try
            {
                string str = null;
                Console.WriteLine(str.GetHashCode());
            }
            catch (Exception ex)
            {
                Loger.Trace(ex, "Trace");
                Loger.Debug(ex, "Debug");
                Loger.Info(ex, "Info");
                Loger.Warn(ex, "Warn");
                Loger.Error(ex, "Error");
                Loger.Fatal(ex, "Fatal");
            }
        }
        


        private static void TestMemoryPoolZPeromance2()
        {
            Stopwatch stopwatch = new Stopwatch();
            int perTestCount = 10000;

            int[] blockAlignedSizes = new int[] { 80, 200, 800, 3000, 8000, 15000, 25000, 35000, 45000, 55000, 65000 };

            List<double> values = new List<double>();
            int testCount = 20;

            var options = new MemoryPoolZOption[]
            {
                new MemoryPoolZOption(100,100),
                new MemoryPoolZOption(500,100),
                new MemoryPoolZOption(1000,100),
                new MemoryPoolZOption(5000,100),
                new MemoryPoolZOption(10000,100),
                new MemoryPoolZOption(20000,100),
                new MemoryPoolZOption(30000,100),
                new MemoryPoolZOption(40000,100),
                new MemoryPoolZOption(50000,100),
                new MemoryPoolZOption(60000,100),
                new MemoryPoolZOption(70000,100),
            };
            using var pollManager = new MemoryPoolZManager<double>(options, BufferSearchAlgorithmType.Sequence);

            foreach (var blockAlignedSize in blockAlignedSizes)
            {
                values.Clear();
                for (int j = 0; j < testCount; j++)
                {
                    stopwatch.Restart();
                    for (int i = 0; i < perTestCount; i++)
                    {
                        using var memoryBlock = pollManager.Rent(blockAlignedSize);
                        Span<double> data = memoryBlock.Span;
                        for (int k = 0; k < data.Length; k++)
                        {
                            data[k] = k;
                        }
                    }
                    stopwatch.Stop();
                    values.Add(stopwatch.Elapsed.TotalMilliseconds);
                }
                Console.WriteLine($"memoryBlock.Span blockAlignedSize:{blockAlignedSize},test:{testCount}x{perTestCount},平均用时:{Math.Round(values.Average(), 3)}ms");
            }
            Console.WriteLine("----------------------------------------------------------------------------------");
            foreach (var blockAlignedSize in blockAlignedSizes)
            {
                values.Clear();
                for (int j = 0; j < testCount; j++)
                {
                    stopwatch.Restart();
                    for (int i = 0; i < perTestCount; i++)
                    {
                        using var memoryBlock = pollManager.Rent(blockAlignedSize);
                        SpanZ<double> data = memoryBlock.SpanZ;
                        for (int k = 0; k < data.Length; k++)
                        {
                            data[k] = k;
                        }
                    }
                    stopwatch.Stop();
                    values.Add(stopwatch.Elapsed.TotalMilliseconds);
                }
                Console.WriteLine($"memoryBlock.SpanZ blockAlignedSize:{blockAlignedSize},test:{testCount}x{perTestCount},平均用时:{Math.Round(values.Average(), 3)}ms");
            }
            Console.WriteLine("----------------------------------------------------------------------------------");
            foreach (var blockAlignedSize in blockAlignedSizes)
            {
                values.Clear();
                for (int j = 0; j < testCount; j++)
                {
                    stopwatch.Restart();
                    for (int i = 0; i < perTestCount; i++)
                    {
                        using var memoryBlock = pollManager.Rent(blockAlignedSize);
                        double* dataPtr = memoryBlock.DataPtr;
                        for (int k = 0; k < memoryBlock.Length; k++)
                        {
                            dataPtr[k] = k;
                        }
                    }
                    stopwatch.Stop();
                    values.Add(stopwatch.Elapsed.TotalMilliseconds);
                }
                Console.WriteLine($"memoryBlock.DataPtr blockAlignedSize:{blockAlignedSize},test:{testCount}x{perTestCount},平均用时:{Math.Round(values.Average(), 3)}ms");
            }
            Console.WriteLine("----------------------------------------------------------------------------------");
            foreach (var blockAlignedSize in blockAlignedSizes)
            {
                values.Clear();
                for (int j = 0; j < testCount; j++)
                {
                    stopwatch.Restart();
                    for (int i = 0; i < perTestCount; i++)
                    {
                        using var memoryBlock = pollManager.Rent(blockAlignedSize);
                        for (int k = 0; k < memoryBlock.Length; k++)
                        {
                            memoryBlock[k] = k;
                        }
                    }
                    stopwatch.Stop();
                    values.Add(stopwatch.Elapsed.TotalMilliseconds);
                }
                Console.WriteLine($"memoryBlock.Index blockAlignedSize:{blockAlignedSize},test:{testCount}x{perTestCount},平均用时:{Math.Round(values.Average(), 3)}ms");
            }
            Console.WriteLine("----------------------------------------------------------------------------------");
            var pool = System.Buffers.MemoryPool<double>.Shared;
            foreach (var blockAlignedSize in blockAlignedSizes)
            {
                values.Clear();
                for (int j = 0; j < testCount; j++)
                {
                    stopwatch.Restart();
                    for (int i = 0; i < perTestCount; i++)
                    {
                        using System.Buffers.IMemoryOwner<double> blockOwner = pool.Rent(blockAlignedSize);
                        Span<double> block = blockOwner.Memory.Span;
                        for (int k = 0; k < block.Length; k++)
                        {
                            block[k] = k;
                        }
                    }
                    stopwatch.Stop();
                    values.Add(stopwatch.Elapsed.TotalMilliseconds);
                }
                Console.WriteLine($"System.Buffers.MemoryPool blockAlignedSize:{blockAlignedSize},test:{testCount}x{perTestCount},平均用时:{Math.Round(values.Average(), 3)}ms");
            }

        }

    }
}
